﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Com.CMS263.Util
{
   public class ChinaDateTime
    {
        static private readonly string[] chineseYear = new string[]{
                "甲子","乙丑","丙寅","丁卯","戊辰","己巳","庚午","辛未","壬申","癸酉","甲戌","乙亥",
                "丙子","丁丑","戊寅","己卯","庚辰","辛巳","壬午","癸未","甲申","乙酉","丙戌","丁亥",
                "戊子","己丑","庚寅","辛卯","壬辰","癸巳","甲午","己未","丙申","丁酉","戊戌","己亥",
                "庚子","辛丑","壬寅","癸卯","甲辰","乙巳","丙午","丁未","戊申","己酉","庚戌","辛亥",
                "壬子","癸丑","甲寅","乙卯","丙辰","丁巳","戊午","己未","庚申","辛酉","壬戌","癸亥"
        };
        static private readonly string[] chineseMonth = new string[] { 
            "元", "二", "三", "四", "五", "六", "七", "八", "九", "十", "十一", "十二" 
        };
        static private readonly string[] chineseDayOfMonth = new string[] { 
            "初一", "初二", "初三", "初四", "初五", "初六", "初七", "初八", "初九", "十", 
            "十一", "十二","十三", "十四" ,"十五", "十六","十七", "十八" ,"十九", "二十", 
            "廿一", "廿二","廿三", "廿四" ,"廿五", "廿六","廿七", "廿八" ,"廿九", "三十"
        };

        private int year, month, dayOfMonth;
        private bool isLeap;
        public DateTime time;

        public int Year { get { return year; } }
        public int Month { get { return month; } }
        public int DayOfMonth { get { return dayOfMonth; } }
        public bool IsLeap { get { return isLeap; } }

        System.Globalization.ChineseLunisolarCalendar cc;
        public ChinaDateTime(DateTime time)
        {
            cc = new System.Globalization.ChineseLunisolarCalendar();

            if (time > cc.MaxSupportedDateTime || time < cc.MinSupportedDateTime)
                throw new Exception("参数日期时间不在支持的范围内,支持范围：" + cc.MinSupportedDateTime.ToShortDateString() + "到" + cc.MaxSupportedDateTime.ToShortDateString());
            year = cc.GetYear(time);
            month = cc.GetMonth(time);
            dayOfMonth = cc.GetDayOfMonth(time);
            isLeap = cc.IsLeapMonth(year, month);
            if (isLeap) month -= 1;
            this.time = time;
        }
        public static ChinaDateTime Now { get { return new ChinaDateTime(DateTime.Now); } }


        public ChinaDateTime(int Year, int Month, int DayOfMonth, bool IsLeap)
        {
            if (Year >= cc.MaxSupportedDateTime.Year || Year <= cc.MinSupportedDateTime.Year)
                throw new Exception("参数年份时间不在支持的范围内,支持范围：" + cc.MinSupportedDateTime.ToShortDateString() + "到" + cc.MaxSupportedDateTime.ToShortDateString());

            if (Month < 1 || Month > 12)
                throw new Exception("月份必须在1~12范围");
            cc = new System.Globalization.ChineseLunisolarCalendar();

            if (cc.GetLeapMonth(Year) != Month && IsLeap)
                throw new Exception("指定的月份不是当年的闰月");
            if (cc.GetDaysInMonth(Year, IsLeap ? Month + 1 : Month) < DayOfMonth || DayOfMonth < 1)
                throw new Exception("指定的月中的天数不在当前月天数有效范围");
            year = Year;
            month = Month;
            dayOfMonth = DayOfMonth;
            isLeap = IsLeap;
            time = DateTime.Now;
        }
        public DateTime ToDateTime()
        {
            return cc.ToDateTime(year, isLeap ? month + 1 : month, dayOfMonth, time.Hour, time.Minute, time.Second, time.Millisecond);
        }
        public static DateTime ToDateTime(ChinaDateTime CnTime) { return CnTime.ToDateTime(); }
        public static ChinaDateTime ToChinaDateTime(DateTime Time) { return new ChinaDateTime(Time); }
        public string ToSimpleChineseString()
        {
            //return base.ToString();
            return "农历:" + ToChineseYear() + " " + ToChineseMonth() + ToChineseDayOfMonth();
        }
        public string ToChineseYear()
        {
            return ToChineseYear(year);
        }
        static public string ToChineseYear(int yearInt)
        {
            int x = (yearInt - 4) % 60;
            return chineseYear[x];
        }
        public string ToChineseMonth()
        {
            if (isLeap)
                return "闰" + chineseMonth[month - 1] + "月";
            else
                return chineseMonth[month - 1] + "月";
        }
        public string ToChineseDayOfMonth()
        {
            return chineseDayOfMonth[dayOfMonth - 1];
        }

    }

}
